﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace GraphGeneration
{
    public class Generator
    {

        Graph g;

        public Generator()
        {
            g = new Graph();
        }

        public ArrayList PrintGraph()
        {
            return g.PrintGraph();
        }


        public void GenerateGraph(int VertexNumber, int EdgesNumber, bool Undirectional, int MinWeight, int MaxWeight)
        {
                      
            List<Edge> notContains = new List<Edge>();

            g.addVertex();

            for (int i = 0; i < VertexNumber - 1; i++)
            {

                int r = Rand.Next(g.VertexCount);
                int weight = Rand.Next(MaxWeight - MinWeight) + MinWeight;                       

                Vertex v2 = new Vertex(g);
                Vertex v1 = g.VertexList[r];

                g.addVertex(v2);
                Edge e = new Edge(v1, v2, weight);
                g.addEdge(e);

                if (Undirectional)
                {
                    e = new Edge(v2, v1, weight);
                    g.addEdge(e);
                }

            }

           
            for (int i = 0; i < VertexNumber; i++)
            {                                            
                Vertex v1 = g.VertexList[i];   
             
                for (int j = 0; j < VertexNumber; j++)
                {
                    Vertex v2 = g.VertexList[j];

                    int weight = Rand.Next(MaxWeight - MinWeight) + MinWeight;
                    Edge e = new Edge(v1, v2, weight);

                    if (v1.ID != v2.ID && !g.EdgeList.Contains(e, new EdgeComparer()))
                    {
                        
                        notContains.Add(e);
                                       
                    }
                }
            }
            
          
            for (int i = 0; i <= EdgesNumber - VertexNumber; i++)
            {

                int rand = Rand.Next(notContains.Count);
                g.addEdge(notContains[rand]);
                int range = 1;
                if(Undirectional)
                {            
                    range++;                                        
                }

                notContains.RemoveRange(rand,range);
                
            }
        }



        public void GenerateGraphOld2(int VertexNumber, int EdgesNumber, bool Undirectional, int MinWeight, int MaxWeight)
        {

            g.addVertex();
            

            for (int i = 0; i < VertexNumber-1; i++)
            {

                int weight = Rand.Next(MaxWeight - MinWeight) + MinWeight;

                int r = Rand.Next(g.VertexCount);
                Vertex v2 = new Vertex(g);
                Vertex v1 = g.VertexList[r];
                g.addVertex(v2);
                Edge e = new Edge(v1,v2,weight);
                g.addEdge(e);

                if (Undirectional)
                {
                    e = new Edge(v2, v1, weight);
                    g.addEdge(e);
                }

            }


            for (int i = 0; i <= EdgesNumber - VertexNumber; i++)
            {
                Edge e1;
                Edge e2;
                int weight = Rand.Next(MaxWeight - MinWeight) + MinWeight;
                do
                {
                    int r1 = Rand.Next(VertexNumber);
                    int r2;
                    do
                    {
                        r2 = Rand.Next(VertexNumber);
                    } while (r2 == r1);

                    Vertex v1 = g.VertexList[r1];
                    Vertex v2 = g.VertexList[r2];                    

                    e1 = new Edge(v1, v2, weight);
                    e2 = new Edge(v2, v1, weight);
                } while (g.EdgeList.Contains(e1,new EdgeComparer()));
                g.addEdge(e1);
                if (Undirectional)
                {
                    g.addEdge(e2);
                }
            }
        }

        public void GenerateGraphOld(int VertexNumber, int EdgesNumber)
        {

            for (int i = 0; i < VertexNumber; i++)
            {
                g.addVertex();
            }


            for (int i = 0; i < VertexNumber; i++)
            {                
                //if(flagNotAllowPointEdges)
                int r; //Do not allow to make edges (v1,v1)
                do
                {
                    r = Rand.Next(VertexNumber);
                }while(r == i);

                Vertex v1 = g.VertexList[i];         
                Vertex v2 = g.VertexList[r];
                g.addEdge(v1, v2);
            }

            for (int i = 0; i < EdgesNumber - VertexNumber; i++)
            {
                int r1 = Rand.Next(VertexNumber);
                int r2;
                do
                {
                    r2 = Rand.Next(VertexNumber);
                } while (r2 == r1);

                Vertex v1 = g.VertexList[r1];
                Vertex v2 = g.VertexList[r2];
                g.addEdge(v1, v2);

            }            
        }


        public void RerollWeights(int MinWeight, int MaxWeight, bool Undirectional)
        {
            int rand;
            for (int i = 0; i < g.EdgeList.Count; i++)
            {
                rand = Rand.Next(MaxWeight - MinWeight) + MinWeight;
                g.EdgeList[i].Weight = rand;
                if (Undirectional)
                    g.EdgeList[++i].Weight = rand;
            }
        }
        

    }
}
